package com.skytech.component.crawler.web;

import com.alibaba.fastjson.JSONObject;
import com.skytech.component.crawler.parse.ParserLoader;
import com.skytech.component.crawler.parse.SaveDataImpl;
import com.skytech.component.crawler.quartz.QuartzJob;
import com.skytech.component.crawler.quartz.QuartzManager;
import com.skytech.component.crawler.quartz.UpdateCronTask;
import com.skytech.component.crawler.scratch.*;
import com.skytech.component.crawler.task.CrawlerTask;
import org.quartz.JobDataMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.*;

@RestController
public class CrawlerConfigController {
    @Autowired
    private TargetRulesDAO targetRulesDAO;
    @Autowired
    private CustomLocationDAO customLocationDAO;

    @Autowired
    private CrawlerUrlService crawlerUrlService;
    @Autowired
    private CrawlerUrlDAO crawlerUrlDAO;
    @Autowired
    private CrawlerTask crawlerTask;

    @Autowired
    private QuartzConfigDAO quartzConfigDAO;

    @Autowired
    private QuartzConfigService quartzConfigService;

    @Autowired
    private QuartzManager quartzManager;

    @Autowired
    private UpdateCronTask updateCronTask;

    @Autowired
    private TaskStatusDAO taskStatusDAO;

    @Autowired
    private DataFormatDAO dataFormatDAO;

    @Autowired
    private DataTypeService dataTypeService;

    @Autowired
    private DataTypeDAO dataTypeDAO;


    @Autowired
    private ParserLoader parserLoader;

    @Autowired
    private SaveDataImpl saveData;

    @Value("${chrome.driver.path}")
    private String driverPath;

    @GetMapping("crawler/config/getByType/{type}")
    public List<TargetRules> getConfig(@PathVariable String type) {
        TargetRules targetRules = new TargetRules();
        if (!"all".equals(type))
            targetRules.setType(CreatePageType.valueOf(type).toString());
        List<TargetRules> all = targetRulesDAO.findAll(Example.of(targetRules));
        all.sort(Comparator.comparing(TargetRules::getGenerateTime));

        return all;
    }

    @PutMapping("crawler/config/saveOrUpdate")
    public TargetRules updateConfig(@RequestBody TargetRules targetRules) {

        return targetRulesDAO.save(targetRules);
    }

    @PutMapping("crawler/config/add")
    public void add(@RequestBody TargetRules targetRules) {
        targetRules.setId(UUID.randomUUID().toString());
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
        targetRules.setGenerateTime(df.format(new Date()));
        targetRulesDAO.save(targetRules);

    }

    @DeleteMapping("crawler/config/delete/{id}")
    @Transactional
    public void deleteConfig(@PathVariable String id) {
        crawlerUrlDAO.deleteByRuleId(id);
        targetRulesDAO.deleteById(id);

        List<CustomLocation> customLocationList = customLocationDAO.findByRuleId(id);
        for (CustomLocation c : customLocationList) {
            customLocationDAO.delete(c);
        }
        if (!taskStatusDAO.findAllByRuleId(id).isEmpty()) {
            taskStatusDAO.delete(taskStatusDAO.findAllByRuleId(id).get(0));
        }
        if (!quartzConfigDAO.findByRuleId(id).isEmpty()) {
            quartzConfigDAO.delete(quartzConfigDAO.findByRuleId(id).get(0));
        }

    }

    @PostMapping("crawler/preAddConfig")
    public void preAddConfig(@RequestBody TargetRules targetRules){
        List<DataFormat> dataFormatList = dataFormatDAO.findByDataType(targetRules.getDataType().trim());
        List<CustomLocation> customLocationList = new ArrayList<>();
        if(!customLocationDAO.findByRuleId(targetRules.getId()).isEmpty()){
            //customLocationDAO.deleteAll(customLocationDAO.findByRuleId(targetRules.getId()));
        }else{
            for (DataFormat dataFormat : dataFormatList) {
                CustomLocation customLocation = new CustomLocation();
                customLocation.setId(UUID.randomUUID().toString());
                customLocation.setCustomSelect(dataFormat.getDataFormat());
                customLocation.setRuleId(targetRules.getId());
                customLocationList.add(customLocation);

            }
            customLocationDAO.saveAll(customLocationList);
        }


    }

    @PutMapping("crawler/config/parseAdd")
    public List<CustomLocation> parseAdd(@RequestBody List<CustomLocation> customLocationList) {
     /*   for (CustomLocation custom:customLocationList) {
            //custom.setId(UUID.randomUUID().toString());
            customLocationDAO.save(custom)
        }*/

       // String type=targetRulesDAO.findAllById(customLocation.getRuleId()).getDataType();
        return customLocationDAO.saveAll(customLocationList);
    }

    @GetMapping("crawler/config/find/{id}")
    public List<CustomLocation> find(@PathVariable String id) {
        return customLocationDAO.findByRuleId(id);
    }

    @GetMapping("crawler/target/find/{id}")
    public TargetRules findTarget(@PathVariable String id) {
        return targetRulesDAO.findAllById(id);
    }

    @PutMapping("crawler/config/updateParse")
    public List<CustomLocation> updateParse(@RequestBody List<CustomLocation> customLocationlist) {
        return customLocationDAO.saveAll(customLocationlist);
    }

    @DeleteMapping("crawler/config/deleteParse/{id}")
    public void deleteParse(@PathVariable String id) {
        customLocationDAO.deleteById(id);
    }


    @GetMapping("crawler/config/getCawlerUrl")
    public Map<String, Integer> getCawlerUrl() {
        return crawlerUrlService.getCawlerUrl();
    }

    @PostMapping("crawler/config/getCrawlerUrlByRuleId")
    public Page<CrawlerUrl> getCrawlerUrlByRuleId(@RequestBody JSONObject jsonObject) {
        return crawlerUrlService.findByRuleId(jsonObject.get("data").toString(), jsonObject.getInteger("page"));
    }


    @GetMapping("crawler/part/page/{id}")
    public void startSingleTask(@PathVariable String id) {
        updateCronTask.startOneTask(id);
    }

    @PutMapping("crawler/quartz/add")
    public void addTaskQuartz(@RequestBody QuartzConfig quartzConfig) {

        JobDataMap jobDataMap = new JobDataMap();

        quartzManager.addJob(quartzConfig.getRuleId(), quartzConfig.getRuleId(), quartzConfig.getRuleId(), quartzConfig.getRuleId(), QuartzJob.class, quartzConfig.getCron(), jobDataMap, quartzConfig.getRuleId());

        quartzConfigService.addTaskQuartz(quartzConfig);
    }

    @GetMapping("crawler/quartz/get/{id}")
    public List<QuartzConfig> getQuartzConfigById(@PathVariable String id) {
        return quartzConfigDAO.findByRuleId(id);
    }

    @PostMapping("crawler/quartz/modify")
    public void modifyTaskQuartz(@RequestBody QuartzConfig quartzConfig) {
        quartzConfigService.addTaskQuartz(quartzConfig);

        quartzManager.modifyJobTime(quartzConfig.getRuleId(), quartzConfig.getRuleId(), quartzConfig.getRuleId(), quartzConfig.getRuleId(), quartzConfig.getCron());

    }


    @PostMapping("crawler/quartz/cancel")
    public void cancelTaskQuartz(@RequestBody QuartzConfig quartzConfig) {
        quartzConfigService.cancelTaskQuartz(quartzConfig);
        quartzManager.removeJob(quartzConfig.getRuleId(), quartzConfig.getRuleId(), quartzConfig.getRuleId(), quartzConfig.getRuleId());
    }


    @GetMapping("crawler/config/getQuartz")
    public List<QuartzConfig> getQuartz() {
        return quartzConfigDAO.findAll();
    }

    @PostMapping("crawler/dataFormat/addFormat")
    public void addFormat(@RequestBody DataFormat dataFormat) {
        dataFormat.setId(UUID.randomUUID().toString());
        dataFormatDAO.save(dataFormat);
    }

    @GetMapping("crawler/dataFormat/getFormat/{type}")
    public List<DataFormat> getFormat(@PathVariable String type) {
        type = type.trim();
        return dataFormatDAO.findByDataType(type);
    }

    @GetMapping("crawler/dataFormat/getDataType")
    public List<DataType> getDataType() {
        return dataTypeDAO.findAll();
    }

    @PostMapping("crawler/dataFormat/addDataType")
    public void addDataType(@RequestBody JSONObject jsonObject) {

        dataTypeService.createIndex(jsonObject);

    }


    @PostMapping("crawler/dataType/confirmCreate")
    public void createMapping(@RequestBody List<DataFormat> dataFormatList) {

        dataTypeService.createMapping(dataFormatList);

    }


    @GetMapping("crawler/getCssSelector/{id}")
    public List<CustomLocation> getCssSelector(@PathVariable String id){
        return customLocationDAO.findByRuleId(id);
    }


    @DeleteMapping("crawler/dataFormat/delete/{id}")
    public void deleteFormat(@PathVariable String id){
         dataFormatDAO.deleteById(id);
    }


}
